package gui.game;

import gui.menus.FenetreAbstraite;
import gui.menus.Preferences;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

import core.Profile;
import core.Voice;
import core.entities.Card;
import core.entities.DifficultyLevel;
import core.entities.Location;
import core.entities.Symbol;

public class Jeu extends FenetreAbstraite implements ActionListener {

	private static final long serialVersionUID = 1L;

	JLabel imageSouth;
	JLabel imageNorth;
	JLabel imageWest;
	JLabel imageEast;
	JLabel imageCenter;

	Location activePlayer;

	ImageIcon totem;

	JLabel currentPlayerLocationIcon;
	JLabel l_timer;
	JLabel left_cards;

	Timer timer;
	Chrono chrono;

	public Jeu(Profile p, String title, DifficultyLevel level) {
		super(p, title);
		new RunGame(this, p, level).start();
		Voice.getInstance().play("C'est parti");
	}

	private void initWindow() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setUndecorated(true);
		setSize(getToolkit().getScreenSize());
		setLocationRelativeTo(null);
		validate();
		setResizable(false);
	}

	protected void init() {

		initWindow();

		imageSouth = new JLabel(Card.JUNGLE_SPEED_CARD_BACK.getImage());
		imageNorth = new JLabel(Card.JUNGLE_SPEED_CARD_BACK.getImage());
		imageWest = new JLabel(Card.JUNGLE_SPEED_CARD_BACK.getImage());
		imageEast = new JLabel(Card.JUNGLE_SPEED_CARD_BACK.getImage());
		imageCenter = new JLabel(totem);

		Preferences pref = Preferences.getData();
		// Selectionner le totem
		totem = new ImageIcon("../ressources/images/" + pref.getTotem().getName() + ".png");
		imageCenter = new JLabel(totem);
		currentPlayerLocationIcon = new JLabel(new ImageIcon("../ressources/images/etoile.png"));

		Color backgroundColor = pref.getCurrentBackgroundColor();

		imageWest.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
		imageSouth.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
		imageNorth.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
		imageEast.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));

		l_timer = new JLabel("0.00");

		imageCenter.setFont(new Font("sansserif", Font.BOLD, 30));
		imageCenter.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);

		left_cards = new JLabel("Cartes : 0");
		left_cards.setFont(new Font("sansserif", Font.BOLD, 72));
		left_cards.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);

		l_timer.setFont(new Font("sansserif", Font.BOLD, 72));
		l_timer.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);

		GridBagLayout gl = new GridBagLayout();
		GridBagConstraints cst = new GridBagConstraints();
		cst.gridx = 0;
		cst.gridy = 2;
		gl.setConstraints(left_cards, cst);
		cst.gridx = 2;
		cst.gridy = 0;
		gl.setConstraints(l_timer, cst);
		cst.gridx = 1;
		cst.gridy = 2;
		gl.setConstraints(imageSouth, cst);
		cst.gridx = 1;
		cst.gridy = 0;
		gl.setConstraints(imageNorth, cst);
		cst.weightx = 0.05;
		cst.gridx = 0;
		cst.gridy = 1;
		gl.setConstraints(imageWest, cst);
		cst.gridx = 2;
		cst.gridy = 1;
		gl.setConstraints(imageEast, cst);
		cst.gridx = 1;
		cst.gridy = 1;
		gl.setConstraints(imageCenter, cst);
		cst.anchor = GridBagConstraints.LAST_LINE_END;
		cst.gridx = 1;
		cst.gridy = 2;
		gl.setConstraints(currentPlayerLocationIcon, cst);

		setLayout(gl);

		add(imageSouth);
		add(imageNorth);
		add(imageWest);
		add(imageEast);
		add(imageCenter);
		add(l_timer);
		add(left_cards);
		add(currentPlayerLocationIcon);

		changeColor();
	}

	public void setLeftCards(int number) {
		if (!this.left_cards.getText().equals("Cartes : " + Integer.toString(number)))
			this.left_cards.setText("Cartes : " + Integer.toString(number));
	}

	public void setBorder(Location location) {
		Preferences pref = Preferences.getData();
		Color foregroundColor = pref.getCurrentForegroundColor();
		Color backgroundColor = pref.getCurrentBackgroundColor();
		activePlayer = location;
		switch (activePlayer) {
		case WEST:
			imageWest.setBorder(BorderFactory.createLineBorder(foregroundColor, 12));
			imageSouth.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
			imageNorth.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
			imageEast.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
			break;
		case NORTH:
			imageWest.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
			imageSouth.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
			imageNorth.setBorder(BorderFactory.createLineBorder(foregroundColor, 12));
			imageEast.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
			break;
		case EAST:
			imageWest.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
			imageSouth.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
			imageNorth.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
			imageEast.setBorder(BorderFactory.createLineBorder(foregroundColor,	12));
			break;
		case SOUTH:
			imageWest.setBorder(BorderFactory.createLineBorder(backgroundColor,	12));
			imageSouth.setBorder(BorderFactory.createLineBorder(foregroundColor, 12));
			imageNorth.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
			imageEast.setBorder(BorderFactory.createLineBorder(backgroundColor,	12));
			break;
		}
		
		switch (foregroundColor.getBlue()) {
		case 150:
			currentPlayerLocationIcon.setIcon(new ImageIcon("../ressources/images/etoile_bleu.png"));
			break;
		case 79:
			currentPlayerLocationIcon.setIcon(new ImageIcon("../ressources/images/etoile_slate.png"));
			break;
		case 0:
			currentPlayerLocationIcon.setIcon(new ImageIcon("../ressources/images/etoile_black.png"));
			break;
		}
	}

	public void setCardOnLocation(Location location, Card c) {
		if (c.getImage() == null)
			c = Card.JUNGLE_SPEED_CARD_BACK;
		switch (location) {
		case WEST:
			setWestCard(c);
			if (!c.getSymbol().equals(Symbol.SPECIAL)) {
				Voice.getInstance().playShortMessageWithoutInterruption("A gauche : " + c.getSymbol().name());
			}
			break;
		case NORTH:
			setNorthCard(c);
			if (!c.getSymbol().equals(Symbol.SPECIAL)) {
				Voice.getInstance().playShortMessageWithoutInterruption("En haut : " + c.getSymbol().name());
			}
			break;
		case EAST:
			setEastCard(c);
			if (!c.getSymbol().equals(Symbol.SPECIAL)) {
				Voice.getInstance().playShortMessageWithoutInterruption("A droite : " + c.getSymbol().name());
			}
			break;
		case SOUTH:
			setSouthCard(c);
			if (!c.getSymbol().equals(Symbol.SPECIAL)) {
				Voice.getInstance().playShortMessageWithoutInterruption(c.getSymbol().name());
			}
			break;
		}
	}

	private void setSouthCard(Card c) {
		imageSouth.setIcon(c.getImage());
		repaint();
	}

	private void setNorthCard(Card c) {
		imageNorth.setIcon(c.getImage());
		repaint();
	}

	private void setWestCard(Card c) {
		imageWest.setIcon(c.getImage());
		repaint();
	}

	private void setEastCard(Card c) {
		imageEast.setIcon(c.getImage());
		repaint();
	}

	public void moveTotemToWinner(Location l) { // TODO Check ceci

		Preferences pref = Preferences.getData();
		Color foregroundColor = pref.getCurrentForegroundColor();
		Color backgroundColor = pref.getCurrentBackgroundColor();

		imageCenter.setIcon(null);

		if (l == Location.SOUTH) {
			imageCenter.setText("GAGNANT : TOI");
			imageSouth.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
			imageSouth.setIcon(totem);
		} else if (l == Location.NORTH) {
			imageCenter.setText("GAGNANT : HAUT");
			imageNorth.setBorder(BorderFactory.createLineBorder(backgroundColor, 12));
			imageNorth.setIcon(totem);
		} else if (l == Location.EAST) {
			imageCenter.setText("GAGNANT : DROITE");
			imageEast.setBorder(BorderFactory.createLineBorder(backgroundColor,12));
			imageEast.setIcon(totem);
		} else if (l == Location.WEST) {
			imageCenter.setText("GAGNANT : GAUCHE");
			imageWest.setBorder(BorderFactory.createLineBorder(backgroundColor,12));
			imageWest.setIcon(totem);
		}
		repaint();
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		if (l == Location.SOUTH) {
			imageSouth.setBorder(BorderFactory.createLineBorder(
					foregroundColor, 12));
		} else if (l == Location.NORTH) {
			imageNorth.setBorder(BorderFactory.createLineBorder(
					foregroundColor, 12));
		} else if (l == Location.EAST) {
			imageEast.setBorder(BorderFactory.createLineBorder(foregroundColor,
					12));
		} else if (l == Location.WEST) {
			imageWest.setBorder(BorderFactory.createLineBorder(foregroundColor,
					12));
		}

		imageCenter.setText(null);
		imageCenter.setIcon(totem);
	}

	@Override
	protected String wavAide() {
		return null;
	}

	public void changeColor() {

		Preferences pref = Preferences.getData();
		Color foregroundColor = pref.getCurrentForegroundColor();
		Color backgroundColor = pref.getCurrentBackgroundColor();

		this.getContentPane().setForeground(foregroundColor);
		this.getContentPane().setBackground(backgroundColor);

		left_cards.setForeground(foregroundColor);
		left_cards.setBackground(backgroundColor);

		l_timer.setForeground(foregroundColor);
		l_timer.setBackground(backgroundColor);

		imageCenter.setForeground(foregroundColor);
		imageCenter.setBackground(backgroundColor);
		

		if (activePlayer != null) {
			switch (activePlayer) {
			case WEST:
				setBorder(Location.WEST);
				break;
			case SOUTH:
				setBorder(Location.SOUTH);
				break;
			case NORTH:
				setBorder(Location.NORTH);
				break;
			default:
				setBorder(Location.EAST);
				break;
			}
		}
	}

	@Override
	protected String wavAccueil() {
		return null;
	}

	@Override
	protected String wavRegleJeu() {
		return null;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
	}

	public void restartTimer() {
		chrono.restart();
	}

	public void initTimer() {
		timer = new Timer();
		chrono = new Chrono();
		timer.schedule(chrono, 0, 100);
	}
	
	public int getCurrentTimeAsInt() {
		return new Long(Math.round(chrono.time)).intValue();
	}

	private class Chrono extends TimerTask {
		private double time;

		public Chrono() {
			super();
			time = 0.00;
		}

		@Override
		public void run() {
			time += 0.10;
			l_timer.setText(Double.toString((double) Math.round(time * 100) / 100));
		}

		public void restart() {
			time = 0.00;
		}
	}

	public void rotateTotem() {
		Preferences p = Preferences.getData();
		File input = new File("../ressources/images/" + p.getTotem().getName() + ".png");
		BufferedImage source = null;
		try {
			source = ImageIO.read(input);
		} catch (IOException e) {
			e.printStackTrace();
		}
		AffineTransform transform = new AffineTransform();
		transform.rotate(Math.toRadians(90), source.getHeight() / 2,
				source.getHeight() / 2);

		BufferedImage rotated = new BufferedImage(source.getHeight(),
				source.getWidth(), BufferedImage.TRANSLUCENT);
		Graphics2D gR = rotated.createGraphics();
		gR.drawRenderedImage(source, transform);
		gR.dispose();

		imageCenter.setIcon(new ImageIcon(Toolkit.getDefaultToolkit()
				.createImage(rotated.getSource())));

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		transform = new AffineTransform();
		transform.rotate(Math.toRadians(0), source.getHeight() / 2,
				source.getHeight() / 2);

		rotated = new BufferedImage(source.getHeight(), source.getWidth(),
				BufferedImage.TRANSLUCENT);
		gR = rotated.createGraphics();
		gR.drawRenderedImage(source, transform);
		gR.dispose();

		imageCenter.setIcon(new ImageIcon(Toolkit.getDefaultToolkit()
				.createImage(rotated.getSource())));

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
